#pragma once
#include <iostream>
#include <string>

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

std::string encode(std::string &content)
{
    size_t len = content.size();
    std::string package;
    package += std::to_string(len);
    package += protocol_sep;
    package += content;
    package += protocol_sep;
    return package;
}

// len\nx oper y\n
// package是用来拆开的，而content是用来回传的
bool decode(std::string &package, std::string *content)
{
    size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos)
        return false;
    std::string len_content = package.substr(0, pos); // 闭区间
    size_t len = std::stoi(len_content); // 报头
    size_t total_len = len + len_content.size() + 2;
    // std::cout << package.size() << " " << total_len << std::endl;
    if (package.size() < total_len) // 校验:长度是否够一个报文大小
    {
        return false;
    }

    *content = package.substr(pos + 1, len);
    package.erase(0, total_len);
    return true;
}

class request
{
public:
    // 构造
    request(int data1, char op, int data2)
        : x(data1),
          oper(op),
          y(data2)
    {
    }
    request()
    {
    }

public:
    bool Serialize(std::string *out)
    {
        std::string s;
        s += std::to_string(x);
        s += blank_space_sep;
        s += oper;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
        return true;
    }
    bool Deserialize(const std::string &in)
    {
        std::size_t left = in.find(blank_space_sep);
        if (left == std::string::npos)
            return false;
        std::string part_x = in.substr(0, left);

        std::size_t right = in.rfind(blank_space_sep);
        if (right == std::string::npos)
            return false;
        std::string part_y = in.substr(right + 1);

        if (left + 2 != right)
            return false;

        oper = in[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);
        return true;
    }

    void DebugPrint()
    {
        std::cout << "新请求构建完成:  " << x << oper << y << "=?" << std::endl;
    }

public:
    int x;
    int y;
    char oper;
};

class response
{
public:
    // 构造
    response(int res, int c)
        : result(res),
          code(c)
    {
    }
    response()
    {
    }

public:
    bool Serialize(std::string *out)
    {
        std::string s;
        s += std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *out = s;
        return true;
    }
    bool Deserialize(const std::string &in)
    {
        std::size_t left = in.find(blank_space_sep);
        if (left == std::string::npos)
            return false;
        std::string part1 = in.substr(0, left);
        std::string part2 = in.substr(left + 1);
        result = std::stoi(part1);
        code = std::stoi(part2);
        return true;
    }

    void DebugPrint()
    {
        std::cout << "结果响应完成, result: " << result << ", code: " << code << std::endl;
    }

public:
    int result;
    int code;
};